/*
 * Copyright 2009-2010 the original author or authors.
 *
 * Licensed under the Apache license, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.internna.iwebjtracker.server.scm;

import java.util.Set;
import java.util.List;
import org.internna.iwebjtracker.server.Server;
import org.internna.iwebjtracker.project.model.Module;
import org.internna.iwebjtracker.project.model.Project;
import org.internna.iwebjtracker.project.model.Version;
import org.internna.iwebjtracker.server.scm.model.Change;
import org.internna.iwebjtracker.server.scm.model.LogEntry;
import org.internna.iwebjtracker.server.scm.model.Revision;
import org.internna.iwebjtracker.server.scm.model.ItemData;
import org.internna.iwebjtracker.server.scm.model.ItemInfo;
import org.internna.iwebjtracker.project.validation.Errors;
import org.internna.iwebjtracker.project.model.IWebJTrackerUser;
import org.internna.iwebjtracker.server.connection.ServerConnection;
import org.internna.iwebjtracker.server.connection.ConnectionDetails;

/**
 * A revision control server.
 *
 * @author Jose Noheda
 * @since 1.0
 */
public interface SourceControlManagementServer<T extends ServerConnection, C extends ConnectionDetails, M extends Module<P, M>, V extends Version<U, P, V>, U extends IWebJTrackerUser, P extends Project<C, M, V, U, P>, I extends ItemInfo<C, M, V, U, P>, R extends Revision, G extends Change, L extends LogEntry<R, G>> extends Server<T, C> {

    /**
     * Loads the item contents.
     */
    ItemData loadItem(I item);

    /**
     * Loads the item contents without having or needing the item information first.
     */
    ItemData loadItem(P project, String url);

    /**
     * Loads the item contents given an existing connection.
     */
    ItemData loadItem(T connection, I item);

    /**
     * Loads the item contents without having or needing the item information first using a provided connection.
     */
    ItemData loadItem(T connection, P project, String url, boolean binary);

    /**
     * Gets all the information available for one destination.
     *
     * @param project a non null Project
     * @param absolutePath a non null string
     * @return a non null object as long as the path matches something (file or folder) in the server.
     */
    I getItemInfo(P project, String absolutePath);

    /**
     * Returns all item information from items placed under this path.
     *
     * @param project a non null Project
     * @param absolutePath a non null String
     * @return a non null collection
     */
    Set<I> getSubItems(P project, String absolutePath);

    /**
     * Returns all item information from items placed under this item.
     *
     * @param project a non null Project
     * @param itemInfo a non null String
     * @return a non null collection
     */
    Set<I> getSubItems(P project, I itemInfo);

    /**
     * Returns the modifications in the item pointed by this path caused by the last commit.
     *
     * @param project a non null Project
     * @param absolutePath a non null String
     * @return the changes in the contents in a unified diff format (if possible).
     */
    String getUnifiedDiff(P project, String absolutePath);

    /**
     * Returns the modifications in this item caused by the last commit.
     *
     * @param project a non null Project
     * @param itemInfo a non null ItemInfo object with not empty path info
     * @return the changes in the contents in a unified diff format (if possible).
     */
    String getUnifiedDiff(P project, I itemInfo);

    /**
     * Tests project configuration using this server (usually test a connection).
     *
     * @param project any project
     * @return null or an error
     */
    Errors validateProject(P project);

    /**
     * Polls SCM to get the log entries between two revisions of a project.
     *
     * @param project any
     * @param from any
     * @param to any
     * @return any
     */
    List<L> log(P project, R from, R to);

    /**
     * Polls SCM to get the log entries between two revisions using the provided connection.
     *
     * @param connection any
     * @param from any
     * @param to any
     * @return any
     */
    List<L> log(T connection, P project, R from, R to);

}
